<template>
  <!-- 文件上传 -->
  <div class="pho-form-item">
    <div
      style="display: flex; justify-content: space-between"
      :style="isTop ? 'flex-direction: column;' : ''"
    >
      <van-field
        class="form-input-hidden"
        v-bind="$attrs"
        :value="value"
        :name="$attrs.__vModel__"
        readonly
        :label="showLabel ? label : ''"
        :label-width="labelWidth"
        :required="required"
        input-align="right"
      />
      <van-uploader
        style="padding: 0 16px 10px 16px"
        :readonly="readonly"
        :disabled="disabled"
        :multiple="multiple"
        :max-size="maxSize"
        :max-count="limit"
        :accept="accept"
        :preview-image="false"
        :after-read="afterRead"
        @oversize="onOversize"
      >
        <div class="form-upload-button">
          <svg-icon iconClass="addSold" />
        </div>
        <div class="form-upload-tips" v-if="showTip">*{{ tips }}</div>
      </van-uploader>
    </div>
    <!-- 展示栏 -->
    <FilesShow
      v-if="fileList.length"
      :value.sync="fileList"
      isEdit
      :readonly="readonly"
      :dName="dName"
      :download="download"
      style="padding: 0 16px 10px 16px"
      @change="handleChange"
    />
  </div>
</template>

<script>
import { formatFile } from "../../utils/index";
import { Toast } from "vant";
import { requestPost2 } from "@/api/data";
import FilesShow from "./components/filesShow";
export default {
  name: "phone-form-upload",
  components: {
    FilesShow,
  },
  model: {
    prop: "value", // 绑定的值，通过父组件传递
    event: "update",
  },
  props: {
    // value 和 formValue 存储的都是选择的文件，前者是字符串形式，后者为数组形式
    // 选择的文件的字符串形式
    value: {
      default: "",
    },
    // 是否为上下布局
    isTop: {
      type: Boolean,
      default: false,
    },
    // 标签
    label: {
      type: String,
      default: "",
    },
    // 是否必填
    required: {
      type: Boolean,
      default: false,
    },
    // 文件上传地址
    action: {
      type: String,
      default: "",
    },
    // 下载地址
    download: {
      type: String,
      default: "",
    },
    // 	下载的文件字段名
    dName: {
      type: String,
      default: "",
    },

    // 文件大小
    fileSize: {
      type: [String, Number],
      default: 50,
    },
    // 文件单位
    sizeUnit: {
      type: String,
      default: "MB",
    },
    // 是否只读，仅作展示
    readonly: {
      type: Boolean,
      default: false,
    },
    // 是否展示文件提示语,默认展示
    showTip: {
      type: Boolean,
      default: true,
    },
    // 文件类型
    accept: {
      type: String,
      default: "",
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false,
    },
    // 禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // label标题的宽度
    labelWidth: {
      type: [String, Number],
      default: "100%",
    },
    // 	上传的文件字段名
    name: {
      type: String,
      default: "",
    },
    // 最大允许上传个数
    limit: {
      type: Number,
      default: 10,
    },
    // 是否展示标题
    showLabel: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      fileList: [
        // {
        //   name: "food.jpeg",
        //   url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
        // },
        // {
        //   name: "food2.jpeg",
        //   url: "https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100",
        // },
      ],
      formatFile,
    };
  },

  computed: {
    maxSize() {
      const fileSize = this.fileSize; // 文件大小
      const fileUnit = this.sizeUnit; // 文件单位
      // 实际上传的文件大小单位为B，需要将文件大小限制的单位转换为B
      const maxSize =
        fileSize *
        { KB: 1024, MB: Math.pow(1024, 2), GB: Math.pow(1024, 3) }[fileUnit];
      return maxSize;
    },
    tips() {
      // 最大上传文件+单位
      const sizeUnit = this.fileSize + this.sizeUnit;
      if (this.accept) {
        return `只能上传${this.accept}文件，且不超过${sizeUnit}的文件`;
      }
      return `只能上传不超过${sizeUnit}的文件`;
    },
  },
  watch: {
    value: {
      immediate: true,
      deep: true,
      handler: function (nd, od) {
        try {
          // 回显
          this.fileList = JSON.parse(nd) || [];
        } catch (error) {
          console.log("error", error);
        }
      },
    },
  },

  methods: {
    onOversize() {
      Toast.fail("文件大小不允许上传！");
    },

    // 文件读取完成后的回调函数
    afterRead(file) {
      if (this.fileList.length >= this.limit) {
        return Toast(`最多允许上传${this.limit}个文件`);
      }
      let formData = new FormData();
      if (Array.isArray(file)) {
        // 选择多个文件
        file.forEach((item) => {
          formData.append(this.name, item.file);
          this.fileList.push({
            id: item.file?.lastModified,
            name: item.file?.name,
            url: "",
          });
        });
      } else {
        // 选择单个文件
        formData.append(this.name, file.file);
        this.fileList.push({
          id: file.file?.lastModified,
          name: file.file?.name,
          url: "",
        });
      }
      requestPost2(this.action, formData)
        .then((res) => {
          let fileArr = JSON.parse(this.value || "[]");
          Toast.success("上传成功！");
          try {
            res.mFilePath.forEach((path, index) => {
              fileArr.push({
                id: res.idList[index],
                name: res.mFileName[index],
                url: path,
              });
              this.handleChange(fileArr);
            });
          } catch (error) {
            Toast.fail("上传失败！");
            this.fileList = JSON.parse(this.value || "[]");
          }
        })
        .catch((error) => {
          Toast.fail("上传失败！");
          this.fileList = JSON.parse(this.value || "[]");
        });
    },

    handleChange(fileArr) {
      this.$emit("update", fileArr.length ? JSON.stringify(fileArr) : null);
    },
  },
};
</script>

<style lang="scss" scoped>
@import "@/style/color";
.form-upload-tips {
  margin-top: 5px;
  font-size: 13px;
  color: $blue;
}
.form-upload-button {
  color: $blue;
  font-size: 48px;
  display: inline-block;
}
</style>
